//
//  MTTagFlowLayout.swift
//  MT
//
//  Created by M on 2020/3/12.
//  Copyright © 2020 张强. All rights reserved.
//

import UIKit

@objc
protocol MTTagFlowLayoutDelegate: UICollectionViewDelegateFlowLayout {
    func tagFlowLayout(_ flowLayout: MTTagFlowLayout, didFinishUpdateContentSize size: CGSize)
}

class MTTagFlowLayout: UICollectionViewFlowLayout {
    
    weak var delegate: MTTagFlowLayoutDelegate?
    
    var itemLength: CGFloat = 0
    
    var contentSize: CGSize = .zero
    
    var attributesArray: [UICollectionViewLayoutAttributes] = []
    
    override func prepare() {
        super.prepare()
        
        contentSize = .zero
        attributesArray.removeAll()
        
        guard let collectionView = self.collectionView, let dataSources = collectionView.dataSource, let delegate = collectionView.delegate as? MTTagFlowLayoutDelegate else { return }
        
        let itemCount = dataSources.collectionView(collectionView, numberOfItemsInSection: 0)
        var maxLeft = sectionInset.left
        var maxTop = sectionInset.top
        
        let contentWidth = collectionView.bounds.width - sectionInset.left - sectionInset.right
        let contentHeight = collectionView.bounds.height - sectionInset.top - sectionInset.bottom
        
        for i in 0..<itemCount {
            let currentIndexPath = IndexPath(item: i, section: 0)
            let attributes = UICollectionViewLayoutAttributes(forCellWith: currentIndexPath)
            
            if self.scrollDirection == .horizontal {
                
                var height = self.itemSize.height
                if let h = delegate.collectionView?(collectionView, layout: self, sizeForItemAt: currentIndexPath).height {
                    height = h
                }
                if height > collectionView.bounds.height - self.sectionInset.bottom {
                    maxTop = self.sectionInset.top
                    maxLeft += (self.minimumLineSpacing + self.itemLength)
                }
                height = CGFloat.minimum(collectionView.bounds.height - maxTop - self.sectionInset.bottom, height)
                attributes.frame = CGRect(x: maxLeft, y: maxTop, width: self.itemLength, height: height)
                maxTop = attributes.frame.maxY + self.minimumInteritemSpacing
                if maxTop >= contentHeight {
                    maxTop = self.sectionInset.top
                    maxLeft = attributes.frame.maxX + self.minimumLineSpacing
                }
                
            } else {
                
                var width = itemSize.width
                if let w = delegate.collectionView?(collectionView, layout: self, sizeForItemAt: currentIndexPath).width {
                    width = w
                }
                if width > collectionView.bounds.width - maxLeft - sectionInset.right {
                    maxLeft = sectionInset.left
                    maxTop += minimumLineSpacing + itemLength
                }
                width = CGFloat.minimum(collectionView.bounds.width - maxLeft - sectionInset.right, width)
                attributes.frame = CGRect(x: maxLeft, y: maxTop, width: width, height: itemLength)
                
                maxLeft = attributes.frame.maxX + minimumInteritemSpacing
                if maxLeft >= contentWidth {
                    maxLeft = self.sectionInset.left
                    maxTop = attributes.frame.maxY + self.minimumLineSpacing
                }
            }
            self.attributesArray.append(attributes)
        }
        
        if itemCount > 0 {
            if scrollDirection == .horizontal {
                self.contentSize = CGSize(width: maxLeft + sectionInset.right + self.itemLength, height: collectionView.bounds.height)
            } else {
                self.contentSize = CGSize(width: collectionView.bounds.width, height: maxTop + self.sectionInset.bottom + self.itemLength)
            }
        }
        
        if let delegate = self.delegate {
            delegate.tagFlowLayout(self, didFinishUpdateContentSize: contentSize)
        }
    }
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        attributesArray
    }
    
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        true
    }
    
    override var collectionViewContentSize: CGSize {
        self.contentSize
    }

}
